package com.ycb.limit;


import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;

/**
 * @author 黄泽群
 * @since 2024-01-03
 */
@Slf4j
public class MyRateLimiterApp {

    public static void main(String[] args) throws Exception {
        RateLimiter rateLimiter = new FixedTimeRateLimiter();
        for (int i = 0; i < 500; i++) {
            rateLimiter.exectRequest();
            TimeUnit.MILLISECONDS.sleep(20L);
        }
    }

    public interface RateLimiter{
        boolean exectRequest();
    }

    /** 滑动窗口 */
    public static class SlidingTimeRateLimiter implements RateLimiter{

        private final int maxSize = 10;
        private int requestSize;


        private long windowsTime;
        private final long windowsSize = 1000L;

        @Override
        public boolean exectRequest() {
            return false;
        }
    }


    /** 固定大小数据桶 */
    public static class FixedTimeRateLimiter implements RateLimiter{
        private final int maxSize = 10;
        private int requestSize;
        private long windowsTime;
        private final long windowsSize = 1000L;

        public synchronized boolean exectRequest(){
            long currentTimeMillis = System.currentTimeMillis();
            if (windowsTime < currentTimeMillis){
                windowsTime = currentTimeMillis + windowsSize;
                requestSize = 0;
            }
            if (requestSize<maxSize){
                requestSize++;
                log.info(" success windowsTime:{} requestSize:{}",windowsTime,requestSize);
                return true;
            }else{
                log.error(" fail windowsTime:{} ",windowsTime);
                return false;
            }
        }

    }

}
